package shinesend.com.cn.level_3_cache.lib;

import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.util.LruCache;
import android.view.animation.Animation;
import android.widget.ImageView;

import com.jakewharton.disklrucache.DiskLruCache;
import com.jakewharton.disklrucache.Util;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by MyPC on 2016/11/23.
 */
public class PanoramaLoader {

    private Context context;
    private static PanoramaLoader loader;
    private DiskLruCache diskLruCache;
    private LruCache<String ,Bitmap> lruCache;
    public static  PanoramaLoader getInstance(Context context){
        if (loader==null){
            loader = new PanoramaLoader(context);
        }
        return loader;
    }

    private PanoramaLoader(Context context){
        this.context = context;
        //获得内存大小;
        final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
        int maxsize = maxMemory/8;
        //内存的缓存
        lruCache = new LruCache<String,Bitmap>(maxsize){
            @Override
            protected int sizeOf(String key, Bitmap value) {
                return value.getByteCount();
            }
        };
        //硬盘的缓存;
        try {
            diskLruCache = DiskLruCache.open(
                    ((PanoramaApp)context.getApplicationContext()).getpConfig().getCacheDir(),getAppVersion(context),1
                    ,100*1024*1024);
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    //将下扎起订单图片添加到ImageView中的
    public void loadInto(String url , final ImageView iamge){
        LoadImage(url, new PanoramaCallBack() {
            @Override
            public void surprise(Bitmap bmp) {
                iamge.setImageBitmap(bmp);
            }
        });
    }

    //加载图片,并有动画的效果;
    public void loadIntoWithAnimate(String url , ImageView iamge, Animation animation){

    }

    //加载图片后调用接口返回Bitmap;
    public void LoadImage(final String url, final PanoramaCallBack callback) {

        (new AsyncTask<String ,Void,Bitmap>(){
            @Override
            protected Bitmap doInBackground(String... params) {
                //开始网络请求
                String link = params[0];
                //内存中获取;
                Bitmap bmp = loadFromeCache(link);
                if (bmp!=null){
                    return bmp;
                }
                //sd 中获取;
                bmp = loadFromSDcard(link);
                if (bmp==null){
                    //从网络中获取;
                    bmp = loadFromeNet(link);
                }
                return bmp;
            }

            @Override
            protected void onPostExecute(Bitmap bitmap) {
                if (bitmap==null){
                    return;
                }
                lruCache.put(getDigestHexToString(url), bitmap);
                //回调;
                callback.surprise(bitmap);
            }
        }).execute(url);
//        Bitmap bmp = null;
//        bmp = loadFromeCache(url);//从内存中获取数据;
//        if (bmp != null) {
//            //
//
//        }
//        bmp = loadFromSDcard(url);//从sdcard 中获取数据;
//        if (bmp!=null){
//            //
//
//        }
//        bmp = loadFromeNet(url);
    }

    //从网络中获取图片;
    private Bitmap loadFromeNet(String url) {
        String name = getDigestHexToString(url);
        Bitmap bmp = null;
        InputStream bis = null;
        try {
            URL link  = new URL(url);
            HttpURLConnection connection = (HttpURLConnection) link.openConnection();
            if (connection.getResponseCode()==HttpURLConnection.HTTP_OK){
                bis = connection.getInputStream();
                //将名字保存到硬盘里;
                DiskLruCache.Editor editor = diskLruCache.edit(name);
                if (editor!=null){
                    OutputStream os = editor.newOutputStream(0);
                    //将in流转化为out流
                    Utils.CopyStream(bis,os);
                    editor.commit();
                }
                diskLruCache.flush();
            }

        } catch (IOException e) {
            e.printStackTrace();
        }finally {
            if (bis!=null){
                try {
                    bis.close();

                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        bmp = loadFromSDcard(url);
        return bmp;
    }

    //从内存中获取数据;
    public Bitmap loadFromeCache(String url){
        String name = getDigestHexToString(url);
        Bitmap bmp = lruCache.get(name);
        return bmp;
    }

    //从sdCard中获取
    public Bitmap loadFromSDcard(String url){
        String name = getDigestHexToString (url);
        try {
            if (diskLruCache.get(name)==null){
                return null;
            }else{
                InputStream is = diskLruCache.get(name).getInputStream(0);
                return BitmapFactory.decodeStream(is);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public int getAppVersion(Context context) {
        try {
            //包的版本号;
            PackageInfo info = context.getPackageManager().getPackageInfo(context.getPackageName(), 0);
            return info.versionCode;
        } catch (PackageManager.NameNotFoundException e) {
            e.printStackTrace();
        }
        return 1;
    }

    //http://blog.csdn.net/ma1kong/article/details/2662997
    //MD5加密;
    private String getDigestHexToString(String url) {
        StringBuffer hexString = new StringBuffer();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(url.getBytes());
            byte[] hash = md.digest();

            for (int i = 0; i < hash.length; i++) {
                if ((0xff & hash[i]) < 0x10) {
                    hexString.append("0"
                            + Integer.toHexString((0xFF & hash[i])));
                } else {
                    hexString.append(Integer.toHexString(0xFF & hash[i]));
                }
            }
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return hexString.toString();
    }
}
